package com.safety51.bi.service;

import com.safety51.bi.entity.ChartConfig;
import com.safety51.bi.entity.MetricConfig;
import com.safety51.bi.entity.ChartConfig;
import com.safety51.bi.entity.MetricConfig;
import lombok.var;
import org.springframework.stereotype.Component;

import java.util.*;
import java.util.stream.Collectors;

@Component
public class EChartsGenerator {

    public Object generateOptions(ChartConfig config, List<Map<String, Object>> data) {
        switch (config.getChartType()) {
            case "line":
                return generateLineChart(config, data);
            case "bar":
                return generateBarChart(config, data);
            case "pie":
                return generatePieChart(config, data);
            case "table":
                return generateTableData(config, data);
            default:
                return generateLineChart(config, data);
        }
    }

    private Map<String, Object> generateLineChart(ChartConfig config, List<Map<String, Object>> data) {
        Map<String, Object> options = new HashMap<>();

        if (config.getDimensions() != null && !config.getDimensions().isEmpty()) {
            String dimensionAlias = config.getDimensions().get(0).getAlias();
            List<Object> xAxisData = data.stream()
                    .map(row -> row.get(dimensionAlias))
                    .collect(Collectors.toList());
            options.put("xAxis", new HashMap<String, Object>() {{
                put("type", "category");
                put("data", xAxisData);
            }});
        }

        if (config.getMetrics() != null && !config.getMetrics().isEmpty()) {
            List<Map<String, Object>> series = new ArrayList<>();
            for (MetricConfig metric : config.getMetrics()) {
                Map<String, Object> seriesItem = new HashMap<>();
                seriesItem.put("name", metric.getAlias());
                seriesItem.put("type", "line");

                List<Object> seriesData = data.stream()
                        .map(row -> row.get(metric.getAlias()))
                        .collect(Collectors.toList());
                seriesItem.put("data", seriesData);

                series.add(seriesItem);
            }
            options.put("series", series);
        }

        options.put("yAxis", Collections.singletonMap("type", "value"));
        options.put("tooltip", Collections.singletonMap("trigger", "axis"));

        return options;
    }

    private Map<String, Object> generatePieChart(ChartConfig config, List<Map<String, Object>> data) {
        if (config.getDimensions().isEmpty() || config.getMetrics().isEmpty()) {
            return Collections.emptyMap();
        }

        String dimensionAlias = config.getDimensions().get(0).getAlias();
        String metricAlias = config.getMetrics().get(0).getAlias();

        List<Map<String, Object>> seriesData = data.stream()
                .map(row -> {
                    Map<String, Object> map = new HashMap<>();
                    map.put("name", row.get(dimensionAlias));
                    map.put("value", row.get(metricAlias));
                    return map;
                })
                .collect(Collectors.toList());

        Map<String, Object> series = new HashMap<>();
        series.put("name", config.getChartName());
        series.put("type", "pie");
        series.put("radius", "60%");
        series.put("data", seriesData);

        Map<String, Object> options = new HashMap<>();
        options.put("tooltip", Collections.singletonMap("trigger", "item"));
        options.put("legend", new HashMap<String, String>() {{
            put("orient", "vertical");
            put("left", "left");
        }});
        options.put("series", Collections.singletonList(series));

        return options;
    }

    private Map<String, Object> generateBarChart(ChartConfig config, List<Map<String, Object>> data) {
        // 类似折线图的实现
        Map<String, Object> lineChart = generateLineChart(config, data);
        // 修改系列类型为bar
        if (lineChart.get("series") instanceof List) {
            List<Map<String, Object>> series = (List<Map<String, Object>>) lineChart.get("series");
            for (Map<String, Object> s : series) {
                s.put("type", "bar");
            }
        }
        return lineChart;
    }

    private Map<String, Object> generateTableData(ChartConfig config, List<Map<String, Object>> data) {
        Map<String, Object> tableData = new HashMap<>();
        tableData.put("columns", getTableColumns(config));
        tableData.put("data", data);
        tableData.put("total", data.size());
        return tableData;
    }

    private List<Map<String, Object>> getTableColumns(ChartConfig config) {
        List<Map<String, Object>> columns = new ArrayList<>();

        if (config.getDimensions() != null) {
            for (var dim : config.getDimensions()) {
                columns.add(new HashMap<String, Object>() {{
                    put("title", dim.getAlias());
                    put("dataIndex", dim.getAlias());
                    put("key", dim.getAlias());
                }});
            }
        }

        if (config.getMetrics() != null) {
            for (var metric : config.getMetrics()) {
                columns.add(new HashMap<String, Object>() {{
                    put("title", metric.getAlias());
                    put("dataIndex", metric.getAlias());
                    put("key", metric.getAlias());
                }});
            }
        }

        return columns;
    }
}